<?php

namespace teamug;

/* 
 * An aid to debugging and development
 * 
 * @author sideshowAnthony
 */

class Dev {

    const NARRATE_TO_OUTPUT = 'NARRATE_TO_OUTPUT';
  
    public static $narration = false;
    private static $narrateTo = null;

    
    /**
     * Tell this class where to send narration to
     * 
     * @param string $destination  Dev::NARRATE_TO_OUTPUT, or a file path
     */    
    public static function setNarrationDestination($destination) {
      self::$narrateTo = $destination;
    }
  
    
    /**
     * Write a message to the specified location
     * The location being that set in Dev::SetNarrationDestination()
     * 
     * @param string $narration 
     */
    private static function writeNarration($narration) {
      $narration = "\n".$narration."\n";
      if (self::$narrateTo===self::NARRATE_TO_OUTPUT) {
        echo $narration;
      } else {
        \error_log($narration, 3, self::$narrateTo);
      }
    }
      

   /**
   * Write a message
   * @param string $message The message
   * @param integer $backtraceSteps Rewinds the backtrace to the line of interest
   */
  public static function narrate($message, $backtraceSteps=1) {
    
    $trace = \debug_backtrace($backtraceSteps);

    
    
    $marker = '';
    if (\count($trace)>1) {
      $t = $trace[1];
      $marker.= (array_key_exists('class', $t)) ? $t['class'].$t['type'] : $t['file'].' ';
      $marker.= (array_key_exists('function', $t)) ? $t['function'].'()' : '';
      $marker.= " from {$t['file']} [{$t['line']}]";
    }
    self::writeNarration("$message\n$marker");
  }

  
  public static function narrateDump($message, $data) {
    self::writeNarration($message."\n".self::generateDataDump($data));
  }
   
  
  /**
   * Dump data, or a data structure
   * Does not show an objects private or protected data, 
   * so use var_dump or print_r in that instance
   * 
   * @param mixed $data Any string, number, class, arrays of arrays of classes ...
   * @param integer $indent Indent from the left hand side. Intended for recursion only
   * @return string Tree representing the passed data
   */
  public static function generateDataDump($data, $indent=0) {
    $retval = '';
    $prefix=\str_repeat(' |  ', $indent);
    if (\is_numeric($data)) { return "Number: $data"; }
    elseif (\is_string($data)) { return "String: '$data'"; }
    elseif (\is_null($data)) { return "NULL"; }
    elseif ($data===true) { return "TRUE"; }
    elseif ($data===false) { return "FALSE"; }
    elseif (is_array($data)) {
      $retval.= "Array (".count($data).')';
      $indent++;
      foreach($data AS $key => $value) {
        $retval.= "\n$prefix [$key] = ";
        $retval.= self::generateDataDump($value, $indent);
      }
    }
    elseif (is_object($data)) {
      $retval.= "Object (".get_class($data)." public properties)";
      $indent++;
      foreach($data AS $key => $value) {
        $retval.= "\n$prefix $key -> ";
        $retval.= self::generateDataDump($value, $indent);
      }
    }
    return $retval;
  }  
  
  
  public static function assert($bool, $message) {
    $assertion_result_string = $bool ? 'OK' : 'FAIL';
    self::narrate("Assertion $assertion_result_string: $message", 2);
  }


  
}

